package com.yuan.algorithms.acm2016_1;
/*
 给定n个整数，请统计每个整数出现的次数，按出现次数从多到少的顺序输出。如果两个整数出现次数相同，则先输出值较小的那个。
 样例输入
 12 5 2 3 3 1 3 4 2 5 2 3 5
 样例输出
 3 4
 2 3
 5 3
 1 1
 4 1
 */
import java.util.Arrays;
import java.util.Scanner;

/**
 * @author YouYuan
 * @contact 1265161633@qq.com
 * @date 2016年2月2日 下午8:57:25
 * @descript
 */
public class 整数出现次数排序 {

	static class Node {
		int num;
		int s;// 数字出现次数
		Node next = null;//链式存储出现次数相同的元素

		public Node(int num, int s) {
			this.num = num;
			this.s = s;
		}
	}

	static final int MAXLEN = 100000000;
	static final int MAX = MAXLEN >> 1;
	static int[] arr = new int[MAXLEN];
	static Node[] sort = new Node[MAXLEN];
	static Scanner in = new Scanner(System.in);

	public static void main(String[] args) {
		while (in.hasNext()) {
			int n = in.nextInt();
//			Arrays.fill(arr, 0);//此初始化数组方式太浪费资源
//			Arrays.fill(sort, null);
			for (int i = 0; i < n; i++) {
				int m = in.nextInt();
				arr[m + MAX]++;//hash存储元素以及元素出现的次数
			}
			
			//获取每个元素和元素出现的次数，并按照出现次数进行hash存储
			for (int i = 0; i < arr.length; i++) {
				if (arr[i] != 0) {
					int num = i - MAX;
					int s = arr[i];
					if (sort[s] == null) {
						sort[s] = new Node(num, s);
					} else {
						Node node = sort[s];
						while (node.next != null) {
							node = node.next;
						}
						node.next = new Node(num, s);
					}
					arr[i] = 0;//初始化数组的优化实现。删除已使用的元素，恢复数组默认值
				}
			}
			
			//输出结果
			for (int i = sort.length - 1; i >= 0; i--) {
				if (sort[i] != null) {
					Node t = sort[i];
					System.out.println(t.num + " " + t.s);
					while (t.next != null) {
						t = t.next;
						System.out.println(t.num + " " + t.s);
					}
					sort[i] = null;//删除元素，恢复数组默认值
				}
			}
		}
	}

}
